/*************************************************************************
    > File Name: client.cpp
    > Author: Lancer
    > Mail: 18826075768@163.com
************************************************************************/

#include <iostream>
#include <unistd.h>
#include <pthread.h>

using namespace std;

int total_ticket_num = 100;
pthread_mutex_t my_mutex = PTHREAD_MUTEX_INITIALIZER;

void* sell_ticket1(void* arg){
    for(int i = 0; i < 100; i++){
        pthread_mutex_lock(&my_mutex);
        if(total_ticket_num > 0){
            cout << "sell ticket1 sell the " << 20 - total_ticket_num + 1 << "th ticket" << endl;
            total_ticket_num--;
        }
        pthread_mutex_unlock(&my_mutex);
    }
    return (void*)0;
}

void* sell_ticket2(void* arg){
    int ret = 0;
    for(int i = 0; i < 20; i++){
        ret = pthread_mutex_trylock(&my_mutex);
        if(ret == EBUSY){
            cout << "sell ticket2 : the variable is locked by sell ticket1!" << endl;
        }
        else if(ret == 0){
            if(total_ticket_num > 0){
                cout << "sell ticket2 sell the " << 20 - total_ticket_num + 1 << "th ticket" << endl;
                total_ticket_num--;
            }
            pthread_mutex_unlock(&my_mutex);
        }
    }
    return (void*)0;
}
int main(){
    int ret;
    pthread_t tids[2];
    int i = 0;

    ret = pthread_create(&tids[0], NULL, &sell_ticket1, NULL);
    if(ret){
        cout << "create thread error, ret = " << ret << endl;
        return ret;
    }

    ret = pthread_create(&tids[1], NULL, &sell_ticket2, NULL);
    if(ret){
        cout << "create thread error, ret = " << ret << endl;
        return ret;
    }
    sleep(30);
    void* retval;
    ret = pthread_join(tids[0], &retval);
    if(ret){
        cout << "tid = " << tids[0] << "join error, ret = " << ret << endl;
        return ret;
    }
    cout << "retval = " << (long*)retval << endl;

    ret = pthread_join(tids[1], &retval);
    if(ret){
        cout << "tid = " << tids[1] << "join error, ret = " << ret << endl;
        return ret;
    }
    cout << "retval = " << (long*)retval << endl;
    return 0;
}